#include "vssocket.h"
#include "startsettings.h"
#include <qdebug.h>
VSSocket::VSSocket(QObject *parent) :
    QTcpSocket(parent)
{
	mes=waiting;nextBlockSize=0;
	connect(this,SIGNAL(readyRead()),this,SLOT(readClient()));
}
void VSSocket::readClient()
{
	emit sendMsg(tr("read\n"));
	qDebug()<<"read";
	QDataStream in(this);
	in.setVersion(QDataStream::Qt_4_7);
	if(mes==waiting)
	{
		if(bytesAvailable()<sizeof(qint8))
			return;
		quint8 m;
		in>>m;
		mes=static_cast<MessageType>(m);
		qDebug()<<mes;
	}
	if(nextBlockSize==0)
	{
		if(bytesAvailable()<sizeof(quint16))
			return;
		in>>nextBlockSize;
		qDebug()<<nextBlockSize<<bytesAvailable();
	}
	if(bytesAvailable()<nextBlockSize)
		return;
	Steps st;QString s;
	switch(mes)
	{
	case welcome:
		quint16 ver;
		in>>ver;
		if(ver!=NETVERSION)
		{
			sendErrorMessage(versionWrong);
		}
		in>>nickName;
		emit sendMsg(tr("Received welcome message from ")+nickName+"\n");
		emit ready();
		break;
	case step:
		int d;
		in>>d;

		st.d=d;
		emit moved(st.si(),st.sj(),st.ei(),st.ej());
		qDebug()<<"move";
		break;
	case talk:

		in>>s;
		emit talked(s);
		break;
	case error:
		quint8 er;
		in>>er;
		switch(static_cast<ErrorType>(er))
		{
		case full:
			emit erred(tr("Server is full of players.\n"));
			break;
		case versionWrong:
			emit erred(tr("Server is runed in a different version.\n"));
			break;
		default:
			emit erred(tr("Unknow error!\n"));
			break;
		}
		break;
	case start:
		bool b;
		in>>b;
		StartSettings::playerColor=b;
		emit started();
		break;
	default:
		sendErrorMessage(unknow);
		break;
	}
	nextBlockSize=0;
	mes=waiting;
	//out.device()->seek(0);
	//out<<quint16(block.size()-sizeof(quint16));
	//write(block);
}

void VSSocket::sendWelcomeMessage()
{
	emit sendMsg(tr("Send Welcome message\n"));
	QByteArray block;
	QDataStream out(&block,QIODevice::WriteOnly);
	out<<static_cast<quint8>(welcome);
	out<<quint16(0);
	out<<quint16(NETVERSION);
	out<<StartSettings::nickName;
	out.device()->seek(sizeof(quint8));
	out<<quint16(block.size()-sizeof(quint16)-sizeof(quint8));
	write(block);
}

void VSSocket::sendErrorMessage(ErrorType e)
{
	emit sendMsg(tr("Send Err\n"));
	QByteArray block;
	QDataStream out(&block,QIODevice::WriteOnly);
	out<<static_cast<quint8>(error);
	out<<quint16(0);
	out<<static_cast<quint8>(e);
	out.device()->seek(sizeof(quint8));
	out<<quint16(block.size()-sizeof(quint16)-sizeof(quint8));
	write(block);
}

void VSSocket::sendStepMessage(const Steps &s)
{
	QByteArray block;
	QDataStream out(&block,QIODevice::WriteOnly);
	out<<static_cast<quint8>(step);
	out<<quint16(0);
	out<<s.d;
	out.device()->seek(sizeof(quint8));
	out<<quint16(block.size()-sizeof(quint16)-sizeof(quint8));
	write(block);
}

void VSSocket::sendTalkMessage(const QString &s)
{
	QByteArray block;
	QDataStream out(&block,QIODevice::WriteOnly);
	out<<static_cast<quint8>(talk);
	out<<quint16(0);
	out<<s;
	out.device()->seek(sizeof(quint8));
	out<<quint16(block.size()-sizeof(quint16)-sizeof(quint8));
	write(block);
}
void VSSocket::sendStartMessage(bool color)
{
	QByteArray block;
	QDataStream out(&block,QIODevice::WriteOnly);
	out<<static_cast<quint8>(start);
	out<<quint16(0);
	out<<color;
	out.device()->seek(sizeof(quint8));
	out<<quint16(block.size()-sizeof(quint16)-sizeof(quint8));
	write(block);
}

const QString& VSSocket::getNickName()
{
	return nickName;
}
